<?php
/**
 * @link https://www.kancloud.cn/cleverstone/ymb2
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

namespace common\models;

use builder\helper\Arr;
use yii\base\Component;
use yii\di\Instance;

/**
 * 系统设置组件
 * @author cleverstone
 * @since ym2.0
 */
class SettingService extends Component
{
    /**
     * 缓存驱动
     * @var string|\yii\caching\CacheInterface
     */
    public $cache = 'cache';
    /**
     * 缓存key
     * @var string
     */
    public $cacheKey = 'sys-setting';
    /**
     * 缓存项
     * @var array
     */
    public $items;

    /**
     * @throws \yii\base\InvalidConfigException
     */
    public function init()
    {
        $this->cache = Instance::ensure($this->cache, 'yii\caching\CacheInterface');
    }

    /**
     * 读取配置
     * @param string $key 关键字
     * For example:
     * - group.code 指定分组代码
     * - group.* | group. | group 指定分组
     * - null 全部配置
     *
     * @param null $default 默认值
     * @return mixed
     * @throws \Throwable
     */
    public function read($key, $default = null)
    {
        list($group, $code) = $this->formatKey($key);
        $items = $this->loadFromCache();

        if (empty($group) && empty($code)) {
            return $items ?: $default;
        } elseif (empty($code)) {
            return Arr::getValue($items, $group) ?: $default;
        } else {
            $result = Arr::getValue($items, "{$group}.{$code}.value");
            if (
                $result === ''
                || $result === null
                || $result === '[]'
                || $result === '{}'
            ) {
                return $default;
            }

            return $result;
        }
    }

    /**
     * 写入配置
     * @param string $code 代码
     * @param string $value 值
     * @param null|string $name 名称
     * @param null|string $group 分组代码
     * @return $this
     */
    public function write($code, $value, $name = null, $group = null)
    {
        if (strpos($code, '.') !== false) {
            list($group, $code) = explode('.', $code);
            $model = Setting::findOne(['group' => $group, 'code' => $code]);
        } else {
            $model = Setting::findOne(['code' => $code]);
        }

        if (empty($model)) {
            $model = new Setting();
        }

        $model->code = $code;
        $model->value = (string)$value;
        !empty($group) && $model->group = $group;
        !empty($name) && $model->name = $name;
        $model->save(false);

        return $this;
    }

    /**
     * 清除所有缓存
     */
    public function invalidateCache()
    {
        $this->cache->delete($this->cacheKey);
        $this->items = null;
    }

    /**
     * 格式化关键字
     * @param string $key 关键字
     *  - group.code
     *  - group.* | group | group.
     *  - null
     *
     * @return array
     */
    protected function formatKey($key)
    {
        if ($key && ($pos = strrpos($key, '.')) !== false) {
            $a = substr($key, 0, $pos);
            $b = substr($key, $pos + 1);
            if (
                $b == '*'
                || $b === false
                || trim($b) === ''
            ) {
                $b = null;
            }
        } elseif ($key) {
            $a = $key;
            $b = null;
        } else {
            $a = null;
            $b = null;
        }

        return [$a, $b];
    }

    /**
     * 从DB获取
     * @return array
     */
    public function getFromDb()
    {
        $data = Setting::query()->all();
        $items = Arr::index($data, 'code', 'group');

        return $items;
    }

    /**
     * 从缓存中加载配置项
     * @return array|null
     */
    protected function loadFromCache()
    {
        if ($this->items !== null) {
            return $this->items;
        }

        $data = $this->cache->get($this->cacheKey);
        if (!empty($data)) {
            $this->items = $data;
            return $this->items;
        }

        $items = $this->getFromDb();
        $this->items = $items;
        $this->cache->set($this->cacheKey, $items);

        return $items;
    }
}